﻿using System;
using System.Diagnostics.Contracts;
using System.IO;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    internal struct DXFALC
    {
        private byte cIndent;
        private byte alc;
        private bool fWrap;
        private byte _alcv;
        private bool fJustLast;
        private byte trot;
        private bool fShrinkToFit;
        private bool fMergeCell;
        private int iIndent;
        private int iReadingOrder;
        private ushort CIndentCDE
        {
            get
            {
                ushort result = 0;
                result |= cIndent;
                if (fShrinkToFit)
                    result |= 0x10;
                if (fMergeCell)
                    result |= 0x20;
                result |= (byte)(iReadingOrder << 6);
                return result;
            }
        }

        public void Read(BinaryReader reader)
        {
            var alcAAlcVB = reader.ReadByte();
            this.alc = (byte) (alcAAlcVB & 0x7);
            this.fWrap = ((alcAAlcVB) & 0x08) != 0;
            this.Alcv = (byte) ((alcAAlcVB >> 4) & 0x07);
            this.fJustLast = (alcAAlcVB & 0x80) != 0;
            Contract.Assert(this.AlcAAlcvB == alcAAlcVB);
            this.trot = reader.ReadByte();
            var cIndentCDE = reader.ReadUInt16();
            this.cIndent = (byte) (cIndentCDE & 0x0F);
            Contract.Assert(cIndent < 15);
            this.fShrinkToFit = (cIndentCDE & 0x10) != 0;
            this.fMergeCell = (cIndentCDE & 0x20) != 0;
            this.iReadingOrder = (cIndentCDE >> 6) & 0x3;
            Contract.Assert(this.CIndentCDE == cIndentCDE);
            this.iIndent = reader.ReadInt32();
        }

        public byte AlcAAlcvB
        {
            get
            {
                byte result = 0;
                result |= alc;
                if (fWrap)
                    result |= 0x08;
                result |= (byte)(Alcv << 4);
                if (fJustLast)
                    result |= 0x80;
                return result;
            }
        }

        public byte Alcv
        {
            get { return _alcv; }
            set { _alcv = value; }
        }

        public byte Alch
        {
            get { return this.alc; }
        }

        public bool WrapText
        {
            get { return this.fWrap; }
        }

        public int TextRotation
        {
            get { return trot; }
        }

        public bool JustLast
        {
            get {
                return fJustLast;
            }
        }

        public int Indentation
        {
            get { return iIndent; }
        }

        public bool ShrinkToFit
        {
            get { return fShrinkToFit; }
        }

        public bool MergeCell
        {
            get {
                return fMergeCell;
            }
        }

        public void Write(BinaryWriter writer)
        {
            writer.Write(this.AlcAAlcvB);
            writer.Write(trot);
            writer.Write(CIndentCDE);
            writer.Write(iIndent);
        }
    }
}